/*
 * Description: process monitor message sender
 */
#include "pch.h"
#include "messenger.h"

namespace PERF {

Messenger::Messenger()
{
    this->Init();
}

Messenger::~Messenger()
{
    if (m_hPipe != INVALID_HANDLE_VALUE) {
        CloseHandle(m_hPipe);
        m_hPipe = INVALID_HANDLE_VALUE;
    }
}

int Messenger::Init()
{
    int ret = this->OpenPipe();
    if (!ret) {
        return ret;
    }

    DWORD dwMode = PIPE_READMODE_MESSAGE;
    if (!SetNamedPipeHandleState(m_hPipe, &dwMode, nullptr, nullptr)) {
        return GetLastError();
    }
    return ERROR_SUCCESS;
}

int Messenger::Send(const std::string &message)
{
    if (m_hPipe == INVALID_HANDLE_VALUE) {
        return ERROR_INVALID_HANDLE;
    }
    LPCTSTR lpMessage = message.c_str();
    DWORD dwBytes = (lstrlen(lpMessage) + 1) * sizeof TCHAR;
    DWORD dwBytesWritten = 0;
    if (!WriteFile(m_hPipe, lpMessage, dwBytes, &dwBytesWritten, nullptr)) {
        return GetLastError();
    }
    return ERROR_SUCCESS;
}

int Messenger::OpenPipe()
{
    while (true) {
        m_hPipe = CreateFile(PIPE_NAME, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr);
        if (m_hPipe != INVALID_HANDLE_VALUE) {
            break;
        }
        if (GetLastError() != ERROR_PIPE_BUSY) {
            return GetLastError();
        }
        if (!WaitNamedPipe(PIPE_NAME, PIPE_CONN_WAIT_DURATION)) {
            return WAIT_TIMEOUT;
        }
    }
    return ERROR_SUCCESS;
}

}  // namespace PERF